home *** CD-ROM | disk | FTP | other *** search
- /* memall.c - main memory allocator.
- From K & R pages 173 - 177.
- Entered - G. R. Mansfield. 84/07/31.
- Ver 1.0-5517.
- */
-
- #include <defstd.h>
-
- #define NALLOC 128 /* units to allocate at once */
-
- typedef int ALIGN; /* forces alignment in 8086 */
-
- union header { /* free block header */
- struct {
- union header *ptr; /* next free block */
- unsigned size; /* size of this free block */
- } s;
- ALIGN x;
- };
-
- typedef union header HEADER;
-
- /* local functions */
- static HEADER *moremem();
-
- /* local data */
- static HEADER base; /* empty list to get started */
- static HEADER *allocp = NULL; /* last allocated block */
- static HEADER *moremem();
-
- BYTE *malloc(nbytes) /* general-purpose storage allocator */
- unsigned nbytes;
- {
- register HEADER *p, *q;
- register int nunits;
- BYTE *bp;
- int i, j;
-
- nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
- if ((q = allocp) == NULL) { /* no free list yet */
- base.s.ptr = allocp = q = &base;
- base.s.size = 0;
- }
- for (p = q->s.ptr; ; q = p, p = p->s.ptr) {
- if (p->s.size >= nunits) { /* big enough */
- if (p->s.size == nunits) /* exactly */
- q->s.ptr = p->s.ptr;
- else { /* allocate tail end */
- p->s.size -= nunits;
- p += p->s.size;
- p->s.size = nunits;
- p->s.ptr = NULL;
- }
- allocp = q;
- return((BYTE *)(p+1));
- }
- if (p == allocp) /* wrapped around free list */
- if ((p = moremem(nunits)) == NULL)
- return(NULL); /* none left */
- }
- }
-
- BYTE *calloc(nelem, elsize)
- unsigned nelem, elsize;
- {
- BYTE *p, *q;
- unsigned n;
-
- n = nelem * elsize;
- if ((p = q = malloc(n)) == NULL)
- return(NULL);
- while (n--)
- *q++ = 0;
- return(p);
- }
-
- static HEADER *moremem(nu) /* ask system for memory */
- unsigned nu;
- {
- BYTE *sbrk();
- register BYTE *cp;
- register HEADER *up;
- register int rnu;
-
- rnu = NALLOC * ((nu+NALLOC-1) / NALLOC);
- cp = sbrk(rnu * sizeof(HEADER));
- /*printf("cp %04x\n", cp);*/
- if ((int)cp == -1) /* no space at all */
- return(NULL);
- up = (HEADER *)cp;
- up->s.size = rnu;
- free((BYTE *)(up+1));
- return(allocp);
- }
-
- free(ap) /* put block ap in free list */
- BYTE *ap;
- {
- register HEADER *p, *q;
-
- p = (HEADER *)ap - 1; /* point to header */
- /*printf("free ap %04x p %04x, s %04x ", p, p->s.ptr, p->s.size);*/
- for (q=allocp; !(p > q && p < q->s.ptr); q=q->s.ptr)
- if (q >= q->s.ptr && (p > q || p < q->s.ptr))
- break; /* at one end or other */
-
- if (p+p->s.size == q->s.ptr) { /* join to upper nbr */
- p->s.size += q->s.ptr->s.size;
- p->s.ptr = q->s.ptr->s.ptr;
- } else
- p->s.ptr = q->s.ptr;
- if (q+q->s.size == p) { /* join to lower nbr */
- q->s.size += p->s.size;
- q->s.ptr = p->s.ptr;
- } else
- q->s.ptr = p;
- allocp = q;
- /*printf("fp %04x p %04x, s %04x ", p, p->s.ptr, p->s.size);
- printf("fq %04x p %04x, s %04x\n", q, q->s.ptr, q->s.size);*/
- }
-